﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Diagnostics;
using System.Windows.Media;
using DSLPedItemWizard.Helpers;
using DSLPedItemWizard.Messages;
using Dsl.Ped.Common;
using Dsl.Ped.Framework.AddIns;
using GalaSoft.MvvmLight.Messaging;

namespace DSLPedItemWizard.ViewModels
{
    /// <summary>
    /// Wizard page that let the user select a specific extension
    /// </summary>
    public class SelectionWizardViewModel : ViewModelBase
    {
        /// <summary>
        /// MEF composition container all available DSLPed add-ins are loaded by this 
        /// composition container
        /// </summary>
        private CompositionContainer compositionContainer;

        /// <summary>
        /// <see cref="Messenger"/> for the communication between wizard pages
        /// </summary>
        private Messenger messenger;

        [ImportMany(typeof(IDslPedAddIn))]
        private IEnumerable<Lazy<IDslPedAddIn, IDslPedAddInMetadata>> availableAddIns { get; set; }

        private Lazy<IDslPedAddIn, IDslPedAddInMetadata> selectedAddIn = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="SelectionWizardViewModel"/> class.
        /// </summary>
        /// <param name="catalog">The catalog for a MEF composition</param>
        /// <param name="messenger">The messenger for the internal communication in the wizard</param>
        public SelectionWizardViewModel(ComposablePartCatalog catalog, Messenger messenger)
        {
            this.InitializeAddIns(catalog);
            this.messenger = messenger;
        }

        /// <summary>
        /// Gets all available AddIns
        /// </summary>
        public IEnumerable<Lazy<IDslPedAddIn, IDslPedAddInMetadata>> AddIns
        {
            get
            {
                return availableAddIns;
            }
        }

        /// <summary>
        /// Gets or sets the currently selected AddIn
        /// </summary>
        public Lazy<IDslPedAddIn, IDslPedAddInMetadata> SelectedAddIn
        {
            get
            {
                return selectedAddIn;
            }
            set
            {
                selectedAddIn = value;
                RaisePropertyChanged(() => Detail);
                RaisePropertyChanged(() => Image);
                RaisePropertyChanged(() => SelectedAddIn);

                messenger.Send<CanFinishMessage>(new CanFinishMessage());
            }
        }

        /// <summary>
        /// Detail of the selected <see cref="selectedAddIn"/>
        /// </summary>
        public string Detail
        {
            get
            {
                if (selectedAddIn == null) return string.Empty;
                return string.Format("File Namespace: {0}\r\nFile Extension: *.dsl\r\nFile Description: {1}", selectedAddIn.Metadata.Namespace, selectedAddIn.Metadata.Description);
            }
        }

        /// <summary>
        /// Get the Uri of the application image
        /// </summary>
        public ImageSource Image
        {
            get
            {
                if (selectedAddIn == null) return null;
                return AddInMetadataHelper.GetAddInImageSource(selectedAddIn.Metadata);
            }
        }


        /// <summary>
        /// Initialize all add-ins that are available to the editor
        /// </summary>
        private void InitializeAddIns(ComposablePartCatalog catalogPart)
        {
            var catalog = new AggregateCatalog();
            this.compositionContainer = new CompositionContainer(catalog);
            catalog.Catalogs.Add(catalogPart);

            try
            {
                this.compositionContainer.ComposeParts(this);
            }
            catch (Exception exc)
            {
                Debug.WriteLine("Error: " + exc);
            }
        }
    }
}
